﻿using System;
using System.IO;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using SGIMail.Models;
using SGIMail.DAL;
using SGIMail.BL;
using System.Threading.Tasks;
using PagedList;

namespace SGIMail.WebClient.Controllers
{
    [Authorize]
    public class EventController : Controller
    {
        DbAccess dbAccess = new DbAccess();

        // GET: /Event/
        public ActionResult Index(string sortOrder, string currentFilter, string searchString, int? page)
        {
            var eventList = dbAccess.GetEvents().ToList();
            List<EventViewModel> dataList = new List<EventViewModel>();

            ViewBag.CurrentSort = sortOrder;
            ViewBag.EventNameSortParm = String.IsNullOrEmpty(sortOrder) ? "name_desc" : "";
            ViewBag.DateSortParm = sortOrder == "Date" ? "date_desc" : "Date";
            ViewBag.EventThemeSortParm = String.IsNullOrEmpty(sortOrder) ? "themeName_desc" : "";

            if (searchString != null)
            {
                page = 1;
            }

            else
            {
                searchString = currentFilter;
            }

            ViewBag.CurrentFilter = searchString;

            if (!String.IsNullOrWhiteSpace(searchString))
            {
                eventList = (eventList.Where(x => x.Name.ToUpper().Contains(searchString.ToUpper())
                                       || x.Theme.ToString().ToUpper().Contains(searchString.ToUpper()))).ToList();
            }

            foreach (var ev in eventList)
            {
                EventViewModel eVM = new EventViewModel();
                eVM.id = ev.EventId;
                eVM.Name = ev.Name;
                eVM.Theme = ev.Theme.ToString();
                eVM.Date = ev.Date;
                eVM.participation = dbAccess.GetEventParticipation(eVM.id);

                dataList.Add(eVM);
            }

            switch (sortOrder)
            {
                case "name_desc":
                    dataList = (dataList.OrderByDescending(x => x.Name)).ToList();
                    break;
                case "Date":
                    dataList = (dataList.OrderBy(x => x.Date)).ToList();
                    break;
                case "date_desc":
                    dataList = (dataList.OrderByDescending(x => x.Date)).ToList();
                    break;
                case "themeName_desc":
                    dataList = (dataList.OrderByDescending(x => x.Theme)).ToList();
                    break;
                default:
                    dataList = (dataList.OrderBy(x => x.Name)).ToList();
                    break;
            }

            int pageSize = 10;
            int pageNumber = (page ?? 1);
            return View(dataList.ToPagedList(pageNumber, pageSize));
        }

        // GET: /Event/ImportFromExcel
        public ActionResult Import()
        {
            ImportViewModel ivm = new ImportViewModel();
            ivm.EventSelectList = new SelectList(dbAccess.GetCurrentEvents(), "EventId", "Name");

            return View(ivm);
        }

        // POST: /Event/ImportFromExcel
        [HttpPost]
        public async Task<ActionResult> Import(ImportViewModel ivm)
        {
            if (ivm.File != null &&
                ivm.File.ContentLength > 0 &&
                Path.GetExtension(ivm.File.FileName) == ".xlsx")
            {
                if (dbAccess.DoEventExist(ivm.EventId))
                {
                    try
                    {
                        Spreadsheet spreadsheet = new Spreadsheet();

                        if (spreadsheet.Validate(ivm.File.InputStream))
                            await dbAccess.SaveSpreadsheetData(spreadsheet.Read(stream: ivm.File.InputStream), eventId: ivm.EventId);

                        else
                        {
                            ivm.EventSelectList = new SelectList(dbAccess.GetCurrentEvents(), "EventId", "Name");
                            ivm.ErrorMessage = "The validation failed for the uploaded file.";
                            return View(ivm);
                        }
                    }

                    catch (FileFormatException ex)
                    {
                        // Logging is needed here.
                        // Since that only '.xlsx' files are allowed the exceptions here will
                        // be errors concerning that the file is corrupted or alike.
                        ivm.EventSelectList = new SelectList(dbAccess.GetCurrentEvents(), "EventId", "Name");
                        ivm.ErrorMessage = ex.Message;
                        return View(ivm);
                    }
                }
            }

            else
            {
                ivm.EventSelectList = new SelectList(dbAccess.GetCurrentEvents(), "EventId", "Name");
                ivm.ErrorMessage = "Check if file is valid and if the file extension is '.xlsx', otherwise " +
                    "try resave the file as '.xlsx'";
                return View(ivm);
            }

            return RedirectToAction("Import", "Event");
        }

        // GET: /Event/Details/5
        public ActionResult Details(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }

            EventViewModel ev = dbAccess.GetEvent(id);
            Session["id"] = id;

            if (ev == null)
            {
                return HttpNotFound();
            }

            return View(ev);
        }

        /// <summary>
        /// Opens and shows a image.
        /// </summary>
        /// <param name="id">Id to the event that contains the image.</param>
        /// <returns>ActionResult showing the image.</returns>
        public ActionResult showImage(int? id)
        {
            Event e = dbAccess.GetEventById(id);
            ViewBag.ImagePath = e.ImagePath;

            return View();
        }

        // GET: /Event/Create
        public ActionResult Create()
        {
            //EventViewModel evm = new EventViewModel();
            //evm.ThemeSelectList = new SelectList((Themes[])Enum.GetValues(typeof(Themes)), "id", "Theme");

            return View();
        }

        // POST: /Event/Create
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
        // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create(/*[Bind(Include = "EventId,Name,Theme,ImagePath,RegistrationURL,Date")]*/ EventViewModel ev)
        {
            if (ModelState.IsValid)
            {
                dbAccess.CreateEvent(ev.Event);
                return RedirectToAction("Index");
            }

            return View(ev);
        }

        // GET: /Event/Edit/5
        public ActionResult Edit(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }

            Event ev = dbAccess.GetEventById(id);

            if (ev == null)
            {
                return HttpNotFound();
            }

            return View(ev);
        }

        // POST: /Event/Edit/5
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
        // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<ActionResult> Edit([Bind(Include = "EventId,Name,Theme,ImagePath,RegistrationURL,Date")] Event ev)
        {
            if (ModelState.IsValid)
            {
                await dbAccess.CreateOrUpdateEvent(ev);
                return RedirectToAction("Index");
            }
            return View(ev);
        }

        // GET: /Event/Delete/5
        public ActionResult Delete(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }

            Event ev = dbAccess.GetEventById(id);

            if (ev == null)
            {
                return HttpNotFound();
            }

            return View(ev);
        }

        // POST: /Event/Delete/5
        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public ActionResult DeleteConfirmed(int id)
        {
            dbAccess.DeleteEvent(id);
            return RedirectToAction("Index");
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public ActionResult GetData()
        {
            int id = Convert.ToInt32(Session["id"]);
            IQueryable<EventStatsticsViewModel> data = dbAccess.GetEventStatistics(id);

            return Json(data, JsonRequestBehavior.AllowGet);
        }
    }
}
